From e04c630cb24b65d871f061074bea23174cadf841 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 26 Jul 2005 15:13:56 +0000 Subject: [PATCH] Change from bool indicating blocked to an enum: when watches go synchronous this makes it easier (because then we have two reasons to block) Instead of using return value, use explicit state member inside struct connection. Signed-off-by: Rusty Russel Signed-off-by: Christian Limpach --- tools/xenstore/xenstored_core.c | 310 +++++++++++++++---------- tools/xenstore/xenstored_core.h | 23 +- tools/xenstore/xenstored_domain.c | 90 ++++--- tools/xenstore/xenstored_domain.h | 6 +- tools/xenstore/xenstored_transaction.c | 45 ++-- tools/xenstore/xenstored_transaction.h | 4 +- tools/xenstore/xenstored_watch.c | 48 ++-- tools/xenstore/xenstored_watch.h | 6 +- 8 files changed, 330 insertions(+), 202 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 3eac6407c5..f6f6e71cfc 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -318,7 +318,7 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, list_for_each_entry(i, &connections, list) { if (i->domain) continue; - if (!i->blocked) + if (i->state == OK) FD_SET(i->fd, inset); if (i->out) FD_SET(i->fd, outset); @@ -454,8 +454,7 @@ unsigned int get_strings(struct buffered_data *data, return i; } -/* Returns "false", meaning "connection is not blocked". */ -bool send_reply(struct connection *conn, enum xsd_sockmsg_type type, +void send_reply(struct connection *conn, enum xsd_sockmsg_type type, const void *data, unsigned int len) { struct buffered_data *bdata; @@ -476,16 +475,15 @@ bool send_reply(struct connection *conn, enum xsd_sockmsg_type type, conn->waiting_reply = bdata; } else conn->out = bdata; - return false; } /* Some routines (write, mkdir, etc) just need a non-error return */ -bool send_ack(struct connection *conn, enum xsd_sockmsg_type type) +void send_ack(struct connection *conn, enum xsd_sockmsg_type type) { - return send_reply(conn, type, "OK", sizeof("OK")); + send_reply(conn, type, "OK", sizeof("OK")); } -bool send_error(struct connection *conn, int error) +void send_error(struct connection *conn, int error) { unsigned int i; @@ -494,7 +492,7 @@ bool send_error(struct connection *conn, int error) corrupt(conn, "Unknown error %i (%s)", error, strerror(error)); - return send_reply(conn, XS_ERROR, xsd_errors[i].errstring, + send_reply(conn, XS_ERROR, xsd_errors[i].errstring, strlen(xsd_errors[i].errstring) + 1); } @@ -780,7 +778,7 @@ bool check_node_perms(struct connection *conn, const char *node, return false; } -static bool send_directory(struct connection *conn, const char *node) +static void send_directory(struct connection *conn, const char *node) { char *path, *reply = talloc_strdup(node, ""); unsigned int reply_len = 0; @@ -788,13 +786,17 @@ static bool send_directory(struct connection *conn, const char *node) struct dirent *dirent; node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_READ)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_READ)) { + send_error(conn, errno); + return; + } path = node_dir(conn->transaction, node); dir = talloc_opendir(path); - if (!dir) - return send_error(conn, errno); + if (!dir) { + send_error(conn, errno); + return; + } while ((dirent = readdir(*dir)) != NULL) { int len = strlen(dirent->d_name) + 1; @@ -807,32 +809,35 @@ static bool send_directory(struct connection *conn, const char *node) reply_len += len; } - return send_reply(conn, XS_DIRECTORY, reply, reply_len); + send_reply(conn, XS_DIRECTORY, reply, reply_len); } -static bool do_read(struct connection *conn, const char *node) +static void do_read(struct connection *conn, const char *node) { char *value; unsigned int size; int *fd; node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_READ)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_READ)) { + send_error(conn, errno); + return; + } fd = talloc_open(node_datafile(conn->transaction, node), O_RDONLY, 0); if (!fd) { /* Data file doesn't exist? We call that a directory */ if (errno == ENOENT) errno = EISDIR; - return send_error(conn, errno); + send_error(conn, errno); + return; } value = read_all(fd, &size); if (!value) - return send_error(conn, errno); - - return send_reply(conn, XS_READ, value, size); + send_error(conn, errno); + else + send_reply(conn, XS_READ, value, size); } /* Create a new directory. Optionally put data in it (if data != NULL) */ @@ -876,7 +881,7 @@ static bool new_directory(struct connection *conn, } /* path, flags, data... */ -static bool do_write(struct connection *conn, struct buffered_data *in) +static void do_write(struct connection *conn, struct buffered_data *in) { unsigned int offset, datalen; char *vec[2]; @@ -885,16 +890,20 @@ static bool do_write(struct connection *conn, struct buffered_data *in) struct stat st; /* Extra "strings" can be created by binary data. */ - if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) - return send_error(conn, EINVAL); + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { + send_error(conn, EINVAL); + return; + } node = canonicalize(conn, vec[0]); if (/*suppress error on write outside transaction*/ 0 && - !within_transaction(conn->transaction, node)) - return send_error(conn, EROFS); + !within_transaction(conn->transaction, node)) { + send_error(conn, EROFS); + return; + } if (transaction_block(conn, node)) - return true; + return; offset = strlen(vec[0]) + strlen(vec[1]) + 2; datalen = in->used - offset; @@ -905,32 +914,46 @@ static bool do_write(struct connection *conn, struct buffered_data *in) mode = XS_PERM_WRITE|XS_PERM_CREATE; else if (streq(vec[1], XS_WRITE_CREATE_EXCL)) mode = XS_PERM_WRITE|XS_PERM_CREATE; - else - return send_error(conn, EINVAL); + else { + send_error(conn, EINVAL); + return; + } - if (!check_node_perms(conn, node, mode)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, mode)) { + send_error(conn, errno); + return; + } if (lstat(node_dir(conn->transaction, node), &st) != 0) { /* Does not exist... */ - if (errno != ENOENT) - return send_error(conn, errno); + if (errno != ENOENT) { + send_error(conn, errno); + return; + } /* Not going to create it? */ - if (!(mode & XS_PERM_CREATE)) - return send_error(conn, ENOENT); + if (!(mode & XS_PERM_CREATE)) { + send_error(conn, ENOENT); + return; + } - if (!new_directory(conn, node, in->buffer + offset, datalen)) - return send_error(conn, errno); + if (!new_directory(conn, node, in->buffer + offset, datalen)) { + send_error(conn, errno); + return; + } } else { /* Exists... */ - if (streq(vec[1], XS_WRITE_CREATE_EXCL)) - return send_error(conn, EEXIST); + if (streq(vec[1], XS_WRITE_CREATE_EXCL)) { + send_error(conn, EEXIST); + return; + } tmppath = tempfile(node_datafile(conn->transaction, node), in->buffer + offset, datalen); - if (!tmppath) - return send_error(conn, errno); + if (!tmppath) { + send_error(conn, errno); + return; + } commit_tempfile(tmppath); } @@ -938,163 +961,196 @@ static bool do_write(struct connection *conn, struct buffered_data *in) add_change_node(conn->transaction, node, false); send_ack(conn, XS_WRITE); fire_watches(conn->transaction, node, false); - return false; } -static bool do_mkdir(struct connection *conn, const char *node) +static void do_mkdir(struct connection *conn, const char *node) { node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) { + send_error(conn, errno); + return; + } - if (!within_transaction(conn->transaction, node)) - return send_error(conn, EROFS); + if (!within_transaction(conn->transaction, node)) { + send_error(conn, EROFS); + return; + } if (transaction_block(conn, node)) - return true; + return; - if (!new_directory(conn, node, NULL, 0)) - return send_error(conn, errno); + if (!new_directory(conn, node, NULL, 0)) { + send_error(conn, errno); + return; + } add_change_node(conn->transaction, node, false); send_ack(conn, XS_MKDIR); fire_watches(conn->transaction, node, false); - return false; } -static bool do_rm(struct connection *conn, const char *node) +static void do_rm(struct connection *conn, const char *node) { char *tmppath, *path; node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_WRITE)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_WRITE)) { + send_error(conn, errno); + return; + } - if (!within_transaction(conn->transaction, node)) - return send_error(conn, EROFS); + if (!within_transaction(conn->transaction, node)) { + send_error(conn, EROFS); + return; + } if (transaction_block(conn, node)) - return true; + return; - if (streq(node, "/")) - return send_error(conn, EINVAL); + if (streq(node, "/")) { + send_error(conn, EINVAL); + return; + } /* We move the directory to temporary name, destructor cleans up. */ path = node_dir(conn->transaction, node); tmppath = talloc_asprintf(node, "%s.tmp", path); talloc_set_destructor(tmppath, destroy_path); - if (rename(path, tmppath) != 0) - return send_error(conn, errno); + if (rename(path, tmppath) != 0) { + send_error(conn, errno); + return; + } add_change_node(conn->transaction, node, true); send_ack(conn, XS_RM); fire_watches(conn->transaction, node, true); - return false; } -static bool do_get_perms(struct connection *conn, const char *node) +static void do_get_perms(struct connection *conn, const char *node) { struct xs_permissions *perms; char *strings; unsigned int len, num; node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_READ)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_READ)) { + send_error(conn, errno); + return; + } perms = get_perms(conn->transaction, node, &num); - if (!perms) - return send_error(conn, errno); + if (!perms) { + send_error(conn, errno); + return; + } strings = perms_to_strings(node, perms, num, &len); if (!strings) - return send_error(conn, errno); - - return send_reply(conn, XS_GET_PERMS, strings, len); + send_error(conn, errno); + else + send_reply(conn, XS_GET_PERMS, strings, len); } -static bool do_set_perms(struct connection *conn, struct buffered_data *in) +static void do_set_perms(struct connection *conn, struct buffered_data *in) { unsigned int num; char *node; struct xs_permissions *perms; num = xs_count_strings(in->buffer, in->used); - if (num < 2) - return send_error(conn, EINVAL); + if (num < 2) { + send_error(conn, EINVAL); + return; + } /* First arg is node name. */ node = canonicalize(conn, in->buffer); in->buffer += strlen(in->buffer) + 1; num--; - if (!within_transaction(conn->transaction, node)) - return send_error(conn, EROFS); + if (!within_transaction(conn->transaction, node)) { + send_error(conn, EROFS); + return; + } if (transaction_block(conn, node)) - return true; + return; /* We must own node to do this (tools can do this too). */ - if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_OWNER)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_OWNER)) { + send_error(conn, errno); + return; + } perms = talloc_array(node, struct xs_permissions, num); - if (!xs_strings_to_perms(perms, num, in->buffer)) - return send_error(conn, errno); + if (!xs_strings_to_perms(perms, num, in->buffer)) { + send_error(conn, errno); + return; + } + + if (!set_perms(conn->transaction, node, perms, num)) { + send_error(conn, errno); + return; + } - if (!set_perms(conn->transaction, node, perms, num)) - return send_error(conn, errno); add_change_node(conn->transaction, node, false); send_ack(conn, XS_SET_PERMS); fire_watches(conn->transaction, node, false); - return false; } /* Process "in" for conn: "in" will vanish after this conversation, so * we can talloc off it for temporary variables. May free "conn". - * Returns true if can't complete due to block. */ -static bool process_message(struct connection *conn, struct buffered_data *in) +static void process_message(struct connection *conn, struct buffered_data *in) { switch (in->hdr.msg.type) { case XS_DIRECTORY: - return send_directory(conn, onearg(in)); + send_directory(conn, onearg(in)); + break; case XS_READ: - return do_read(conn, onearg(in)); + do_read(conn, onearg(in)); + break; case XS_WRITE: - return do_write(conn, in); + do_write(conn, in); + break; case XS_MKDIR: - return do_mkdir(conn, onearg(in)); + do_mkdir(conn, onearg(in)); + break; case XS_RM: - return do_rm(conn, onearg(in)); + do_rm(conn, onearg(in)); + break; case XS_GET_PERMS: - return do_get_perms(conn, onearg(in)); + do_get_perms(conn, onearg(in)); + break; case XS_SET_PERMS: - return do_set_perms(conn, in); + do_set_perms(conn, in); + break; case XS_SHUTDOWN: /* FIXME: Implement gentle shutdown too. */ /* Only tools can do this. */ - if (conn->id != 0) - return send_error(conn, EACCES); - if (!conn->can_write) - return send_error(conn, EROFS); + if (conn->id != 0) { + send_error(conn, EACCES); + break; + } + if (!conn->can_write) { + send_error(conn, EROFS); + break; + } send_ack(conn, XS_SHUTDOWN); /* Everything hangs off auto-free context, freed at exit. */ exit(0); case XS_DEBUG: - if (streq(in->buffer, "print")) { + if (streq(in->buffer, "print")) xprintf("debug: %s", in->buffer + get_string(in, 0)); - return false; - } #ifdef TESTING /* For testing, we allow them to set id. */ if (streq(in->buffer, "setid")) { @@ -1107,37 +1163,44 @@ static bool process_message(struct connection *conn, struct buffered_data *in) failtest = true; } #endif /* TESTING */ - return false; + break; case XS_WATCH: - return do_watch(conn, in); + do_watch(conn, in); + break; case XS_WATCH_ACK: - return do_watch_ack(conn, onearg(in)); + do_watch_ack(conn, onearg(in)); + break; case XS_UNWATCH: - return do_unwatch(conn, in); + do_unwatch(conn, in); + break; case XS_TRANSACTION_START: - return do_transaction_start(conn, onearg(in)); + do_transaction_start(conn, onearg(in)); + break; case XS_TRANSACTION_END: - return do_transaction_end(conn, onearg(in)); + do_transaction_end(conn, onearg(in)); + break; case XS_INTRODUCE: - return do_introduce(conn, in); + do_introduce(conn, in); + break; case XS_RELEASE: - return do_release(conn, onearg(in)); + do_release(conn, onearg(in)); + break; case XS_GETDOMAINPATH: - return do_get_domain_path(conn, onearg(in)); + do_get_domain_path(conn, onearg(in)); + break; case XS_WATCH_EVENT: default: eprintf("Client unknown operation %i", in->hdr.msg.type); send_error(conn, ENOSYS); - return false; } } @@ -1152,6 +1215,8 @@ static void consider_message(struct connection *conn) enum xsd_sockmsg_type type = conn->in->hdr.msg.type; jmp_buf talloc_fail; + assert(conn->state == OK); + /* For simplicity, we kill the connection on OOM. */ talloc_set_fail_handler(out_of_mem, &talloc_fail); if (setjmp(talloc_fail)) { @@ -1174,7 +1239,9 @@ static void consider_message(struct connection *conn) */ in = talloc_steal(talloc_autofree_context(), conn->in); conn->in = new_buffer(conn); - if (process_message(conn, in)) { + process_message(conn, in); + + if (conn->state == BLOCKED) { /* Blocked by transaction: queue for re-xmit. */ talloc_free(conn->in); conn->in = in; @@ -1197,7 +1264,7 @@ void handle_input(struct connection *conn) int bytes; struct buffered_data *in; - assert(!conn->blocked); + assert(conn->state == OK); in = conn->in; /* Not finished header yet? */ @@ -1254,12 +1321,13 @@ static void unblock_connections(void) struct connection *i, *tmp; list_for_each_entry_safe(i, tmp, &connections, list) { - if (!i->blocked) + if (i->state == OK) continue; - if (!transaction_covering_node(i->blocked)) { - talloc_free(i->blocked); - i->blocked = NULL; + if (!transaction_covering_node(i->blocked_by)) { + talloc_free(i->blocked_by); + i->blocked_by = NULL; + i->state = OK; consider_message(i); } } @@ -1281,7 +1349,8 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read) if (!new) return NULL; - new->blocked = false; + new->state = OK; + new->blocked_by = NULL; new->out = new->waiting_reply = NULL; new->fd = -1; new->id = 0; @@ -1358,10 +1427,14 @@ void dump_connection(void) list_for_each_entry(i, &connections, list) { printf("Connection %p:\n", i); + printf(" state = %s\n", + i->state == OK ? "OK" + : i->state == BLOCKED ? "BLOCKED" + : "INVALID"); if (i->id) printf(" id = %i\n", i->id); - if (i->blocked) - printf(" blocked on = %s\n", i->blocked); + if (i->blocked_by) + printf(" blocked on = %s\n", i->blocked_by); if (i->waiting_for_ack) printf(" waiting_for_ack TRUE\n"); if (!i->in->inhdr || i->in->used) @@ -1418,7 +1491,6 @@ static void setup_structure(void) permfile = talloc_strdup(root, "/tool/xenstored"); if (!set_perms(NULL, permfile, &perms, 1)) barf_perror("Could not create permissions on %s", permfile); - talloc_free(root); if (mkdir(xs_daemon_transactions(), 0750) != 0) barf_perror("Could not create transaction dir %s", diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 4aae32e95e..75a9bfe0a6 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -47,6 +47,14 @@ struct connection; typedef int connwritefn_t(struct connection *, const void *, unsigned int); typedef int connreadfn_t(struct connection *, void *, unsigned int); +enum state +{ + /* Blocked by transaction. */ + BLOCKED, + /* Completed */ + OK, +}; + struct connection { struct list_head list; @@ -57,8 +65,11 @@ struct connection /* Who am I? 0 for socket connections. */ domid_t id; - /* Are we blocked waiting for a transaction to end? Contains node. */ - char *blocked; + /* Blocked on transaction? */ + enum state state; + + /* Node we are waiting for (if state == BLOCKED) */ + char *blocked_by; /* Is this a read-only connection? */ bool can_write; @@ -100,14 +111,14 @@ bool is_child(const char *child, const char *parent); /* Create a new buffer with lifetime of context. */ struct buffered_data *new_buffer(void *ctx); -bool send_reply(struct connection *conn, enum xsd_sockmsg_type type, - const void *data, unsigned int len); +void send_reply(struct connection *conn, enum xsd_sockmsg_type type, + const void *data, unsigned int len); /* Some routines (write, mkdir, etc) just need a non-error return */ -bool send_ack(struct connection *conn, enum xsd_sockmsg_type type); +void send_ack(struct connection *conn, enum xsd_sockmsg_type type); /* Send an error: error is usually "errno". */ -bool send_error(struct connection *conn, int error); +void send_error(struct connection *conn, int error); /* Canonicalize this path if possible. */ char *canonicalize(struct connection *conn, const char *node); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 08130999cb..167fa7aa23 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -239,7 +239,8 @@ void handle_event(int event_fd) * careful that handle_input/handle_output can destroy conn. */ while ((domain = find_domain(port)) != NULL) { - if (!domain->conn->blocked && buffer_has_input(domain->input)) + if (domain->conn->state == OK + && buffer_has_input(domain->input)) handle_input(domain->conn); else if (domain->conn->out && buffer_has_output_room(domain->output)) @@ -287,33 +288,42 @@ static struct domain *new_domain(void *context, domid_t domid, } /* domid, mfn, evtchn, path */ -bool do_introduce(struct connection *conn, struct buffered_data *in) +void do_introduce(struct connection *conn, struct buffered_data *in) { struct domain *domain; char *vec[4]; - if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) - return send_error(conn, EINVAL); + if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { + send_error(conn, EINVAL); + return; + } - if (conn->id != 0) - return send_error(conn, EACCES); + if (conn->id != 0) { + send_error(conn, EACCES); + return; + } - if (!conn->can_write) - return send_error(conn, EROFS); + if (!conn->can_write) { + send_error(conn, EROFS); + return; + } /* Sanity check args. */ - if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) - return send_error(conn, EINVAL); + if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) { + send_error(conn, EINVAL); + return; + } /* Hang domain off "in" until we're finished. */ domain = new_domain(in, atoi(vec[0]), atol(vec[1]), atol(vec[2]), vec[3]); - if (!domain) - return send_error(conn, errno); + if (!domain) { + send_error(conn, errno); + return; + } /* Now domain belongs to its connection. */ talloc_steal(domain->conn, domain); - - return send_ack(conn, XS_INTRODUCE); + send_ack(conn, XS_INTRODUCE); } static struct domain *find_domain_by_domid(domid_t domid) @@ -328,39 +338,51 @@ static struct domain *find_domain_by_domid(domid_t domid) } /* domid */ -bool do_release(struct connection *conn, const char *domid_str) +void do_release(struct connection *conn, const char *domid_str) { struct domain *domain; domid_t domid; - if (!domid_str) - return send_error(conn, EINVAL); + if (!domid_str) { + send_error(conn, EINVAL); + return; + } domid = atoi(domid_str); - if (!domid) - return send_error(conn, EINVAL); + if (!domid) { + send_error(conn, EINVAL); + return; + } - if (conn->id != 0) - return send_error(conn, EACCES); + if (conn->id != 0) { + send_error(conn, EACCES); + return; + } domain = find_domain_by_domid(domid); - if (!domain) - return send_error(conn, ENOENT); + if (!domain) { + send_error(conn, ENOENT); + return; + } - if (!domain->conn) - return send_error(conn, EINVAL); + if (!domain->conn) { + send_error(conn, EINVAL); + return; + } talloc_free(domain->conn); - return send_ack(conn, XS_RELEASE); + send_ack(conn, XS_RELEASE); } -bool do_get_domain_path(struct connection *conn, const char *domid_str) +void do_get_domain_path(struct connection *conn, const char *domid_str) { struct domain *domain; domid_t domid; - if (!domid_str) - return send_error(conn, EINVAL); + if (!domid_str) { + send_error(conn, EINVAL); + return; + } domid = atoi(domid_str); if (domid == DOMID_SELF) @@ -368,11 +390,11 @@ bool do_get_domain_path(struct connection *conn, const char *domid_str) else domain = find_domain_by_domid(domid); - if (!domain) - return send_error(conn, ENOENT); - - return send_reply(conn, XS_GETDOMAINPATH, domain->path, - strlen(domain->path) + 1); + if (!domain) + send_error(conn, ENOENT); + else + send_reply(conn, XS_GETDOMAINPATH, domain->path, + strlen(domain->path) + 1); } static int close_xc_handle(void *_handle) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index ccdf1dbf60..42c1b3d83d 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -23,13 +23,13 @@ void handle_event(int event_fd); /* domid, mfn, eventchn, path */ -bool do_introduce(struct connection *conn, struct buffered_data *in); +void do_introduce(struct connection *conn, struct buffered_data *in); /* domid */ -bool do_release(struct connection *conn, const char *domid_str); +void do_release(struct connection *conn, const char *domid_str); /* domid */ -bool do_get_domain_path(struct connection *conn, const char *domid_str); +void do_get_domain_path(struct connection *conn, const char *domid_str); /* Returns the event channel handle */ int domain_init(void); diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 0e8372f471..60dcf04130 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -114,7 +114,8 @@ bool transaction_block(struct connection *conn, const char *node) trans = transaction_covering_node(node); if (trans) { start_transaction_timeout(trans); - conn->blocked = talloc_strdup(conn, node); + conn->state = BLOCKED; + conn->blocked_by = talloc_strdup(conn, node); return true; } return false; @@ -239,20 +240,24 @@ static bool copy_dir(const char *src, const char *dst) return true; } -bool do_transaction_start(struct connection *conn, const char *node) +void do_transaction_start(struct connection *conn, const char *node) { struct transaction *transaction; char *dir; - if (conn->transaction) - return send_error(conn, EBUSY); + if (conn->transaction) { + send_error(conn, EBUSY); + return; + } node = canonicalize(conn, node); - if (!check_node_perms(conn, node, XS_PERM_READ)) - return send_error(conn, errno); + if (!check_node_perms(conn, node, XS_PERM_READ)) { + send_error(conn, errno); + return; + } if (transaction_block(conn, node)) - return true; + return; dir = node_dir_outside_transaction(node); @@ -270,12 +275,14 @@ bool do_transaction_start(struct connection *conn, const char *node) talloc_set_destructor(transaction, destroy_transaction); trace_create(transaction, "transaction"); - if (!copy_dir(dir, transaction->divert)) - return send_error(conn, errno); + if (!copy_dir(dir, transaction->divert)) { + send_error(conn, errno); + return; + } talloc_steal(conn, transaction); conn->transaction = transaction; - return send_ack(transaction->conn, XS_TRANSACTION_START); + send_ack(transaction->conn, XS_TRANSACTION_START); } static bool commit_transaction(struct transaction *trans) @@ -301,13 +308,17 @@ static bool commit_transaction(struct transaction *trans) return true; } -bool do_transaction_end(struct connection *conn, const char *arg) +void do_transaction_end(struct connection *conn, const char *arg) { - if (!arg || (!streq(arg, "T") && !streq(arg, "F"))) - return send_error(conn, EINVAL); + if (!arg || (!streq(arg, "T") && !streq(arg, "F"))) { + send_error(conn, EINVAL); + return; + } - if (!conn->transaction) - return send_error(conn, ENOENT); + if (!conn->transaction) { + send_error(conn, ENOENT); + return; + } if (streq(arg, "T")) { if (conn->transaction->destined_to_fail) { @@ -322,11 +333,11 @@ bool do_transaction_end(struct connection *conn, const char *arg) talloc_free(conn->transaction); conn->transaction = NULL; - return send_ack(conn, XS_TRANSACTION_END); + send_ack(conn, XS_TRANSACTION_END); + return; failed: talloc_free(conn->transaction); conn->transaction = NULL; - return false; } diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h index 63baa56000..6abc8a2d19 100644 --- a/tools/xenstore/xenstored_transaction.h +++ b/tools/xenstore/xenstored_transaction.h @@ -22,8 +22,8 @@ struct transaction; -bool do_transaction_start(struct connection *conn, const char *node); -bool do_transaction_end(struct connection *conn, const char *arg); +void do_transaction_start(struct connection *conn, const char *node); +void do_transaction_end(struct connection *conn, const char *arg); /* Is node covered by this transaction? */ bool within_transaction(struct transaction *trans, const char *node); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 70bfbaa595..205b70399c 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -310,19 +310,23 @@ void check_watch_ack_timeout(void) } } -bool do_watch(struct connection *conn, struct buffered_data *in) +void do_watch(struct connection *conn, struct buffered_data *in) { struct watch *watch; char *vec[3]; bool relative; - if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) - return send_error(conn, EINVAL); + if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) { + send_error(conn, EINVAL); + return; + } relative = !strstarts(vec[0], "/"); vec[0] = canonicalize(conn, vec[0]); - if (!check_node_perms(conn, vec[0], XS_PERM_READ)) - return send_error(conn, errno); + if (!check_node_perms(conn, vec[0], XS_PERM_READ)) { + send_error(conn, errno); + return; + } watch = talloc(conn, struct watch); watch->node = talloc_strdup(watch, vec[0]); @@ -335,18 +339,22 @@ bool do_watch(struct connection *conn, struct buffered_data *in) insert_watch(watch); talloc_set_destructor(watch, destroy_watch); trace_create(watch, "watch"); - return send_ack(conn, XS_WATCH); + send_ack(conn, XS_WATCH); } -bool do_watch_ack(struct connection *conn, const char *token) +void do_watch_ack(struct connection *conn, const char *token) { struct watch_event *event; - if (!token) - return send_error(conn, EINVAL); + if (!token) { + send_error(conn, EINVAL); + return; + } - if (!conn->waiting_for_ack) - return send_error(conn, ENOENT); + if (!conn->waiting_for_ack) { + send_error(conn, ENOENT); + return; + } event = list_top(&conn->waiting_for_ack->events, struct watch_event, list); @@ -354,21 +362,24 @@ bool do_watch_ack(struct connection *conn, const char *token) if (!streq(conn->waiting_for_ack->token, token)) { /* They're confused: this will cause us to send event again */ conn->waiting_for_ack = NULL; - return send_error(conn, EINVAL); + send_error(conn, EINVAL); + return; } move_event_onwards(event); conn->waiting_for_ack = NULL; - return send_ack(conn, XS_WATCH_ACK); + send_ack(conn, XS_WATCH_ACK); } -bool do_unwatch(struct connection *conn, struct buffered_data *in) +void do_unwatch(struct connection *conn, struct buffered_data *in) { struct watch *watch; char *node, *vec[2]; - if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) - return send_error(conn, EINVAL); + if (get_strings(in, vec, ARRAY_SIZE(vec)) != ARRAY_SIZE(vec)) { + send_error(conn, EINVAL); + return; + } /* We don't need to worry if we're waiting for an ack for the * watch we're deleting: conn->waiting_for_ack was reset by @@ -380,10 +391,11 @@ bool do_unwatch(struct connection *conn, struct buffered_data *in) if (streq(watch->node, node) && streq(watch->token, vec[1])) { talloc_free(watch); - return send_ack(conn, XS_UNWATCH); + send_ack(conn, XS_UNWATCH); + return; } } - return send_error(conn, ENOENT); + send_error(conn, ENOENT); } #ifdef TESTING diff --git a/tools/xenstore/xenstored_watch.h b/tools/xenstore/xenstored_watch.h index b4a7c88d79..c1ab41d866 100644 --- a/tools/xenstore/xenstored_watch.h +++ b/tools/xenstore/xenstored_watch.h @@ -22,9 +22,9 @@ #include "xenstored_core.h" -bool do_watch(struct connection *conn, struct buffered_data *in); -bool do_watch_ack(struct connection *conn, const char *token); -bool do_unwatch(struct connection *conn, struct buffered_data *in); +void do_watch(struct connection *conn, struct buffered_data *in); +void do_watch_ack(struct connection *conn, const char *token); +void do_unwatch(struct connection *conn, struct buffered_data *in); /* Is this a watch event message for this connection? */ bool is_watch_event(struct connection *conn, struct buffered_data *out); -- 2.30.2